package seatiger.tomcat.naming.resources;

import javax.naming.*;
import javax.naming.directory.*;
import java.io.File;
import java.util.Hashtable;

/**
 * 对DirContext的基础实现
 */
public abstract class BaseDirContext implements DirContext {
    //context中指定的项目路径
    private String docBase;

    private Hashtable env;

    public BaseDirContext(){
        this.env = new Hashtable();
    }

    public BaseDirContext(Hashtable env){
        this.env = env;
    }

    public String getDocBase() {
        return docBase;
    }

    public void setDocBase(String docBase) {
        if(docBase == null){
            throw new IllegalArgumentException("resources.null");
        }
        this.docBase = docBase;
    }

    public void setEnv(Hashtable env) {
        this.env = env;
    }

    /**
     * 根据字符串路径 获取 文件对象
     * @param name
     * @return
     * @throws NamingException
     */
    @Override
    public Object lookup(Name name) throws NamingException {
        return lookup(name.toString());
    }

    @Override
    public abstract Object lookup(String name) throws NamingException;

    /**
     * 将name 和资源对象绑定
     * @param name
     * @param obj
     * @throws NamingException
     */
    @Override
    public void bind(Name name, Object obj) throws NamingException {
        bind(name.toString(),obj);
    }

    @Override
    public abstract void bind(String name, Object obj) throws NamingException;


    /**
     * 重新绑定
     * @param name
     * @param obj
     * @throws NamingException
     */
    @Override
    public void rebind(Name name, Object obj) throws NamingException {
        rebind(name.toString(),obj);
    }

    @Override
    public abstract void rebind(String name, Object obj) throws NamingException;

    /**
     * 解除绑定
     * @param name
     * @throws NamingException
     */
    @Override
    public void unbind(Name name) throws NamingException {
        unbind(name.toString());
    }

    @Override
    public abstract void unbind(String name) throws NamingException;

    /**
     * 重新命名
     * @param oldName
     * @param newName
     * @throws NamingException
     */
    @Override
    public void rename(Name oldName, Name newName) throws NamingException {
        rename(oldName.toString(),newName.toString());
    }

    @Override
    public abstract void rename(String oldName, String newName) throws NamingException;

    @Override
    public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
        return list(name.toString());
    }

    @Override
    public abstract NamingEnumeration<NameClassPair> list(String name) throws NamingException;

    @Override
    public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
        return listBindings(name.toString());
    }

    @Override
    public abstract NamingEnumeration<Binding> listBindings(String name) throws NamingException;

    @Override
    public void destroySubcontext(Name name) throws NamingException {
        destroySubcontext(name.toString());
    }

    @Override
    public abstract void destroySubcontext(String name) throws NamingException;

    @Override
    public Context createSubcontext(Name name) throws NamingException {
        return createSubcontext(name.toString());
    }

    @Override
    public abstract Context createSubcontext(String name) throws NamingException ;

    @Override
    public Object lookupLink(Name name) throws NamingException {
        return lookup(name.toString());
    }

    @Override
    public abstract Object lookupLink(String name) throws NamingException;

    @Override
    public NameParser getNameParser(Name name) throws NamingException {
        return name1 -> new CompositeName(name1);
    }

    @Override
    public NameParser getNameParser(String name) throws NamingException {
        return name1 -> new CompositeName(name1);
    }

    @Override
    public Name composeName(Name name, Name prefix) throws NamingException {
        prefix = (Name) name.clone();
        return prefix.addAll(name);
    }

    @Override
    public String composeName(String name, String prefix) throws NamingException {
        return prefix + File.separator + name;
    }

    @Override
    public Object addToEnvironment(String propName, Object propVal) throws NamingException {
        return env.put(propName,propVal);
    }

    @Override
    public Object removeFromEnvironment(String propName) throws NamingException {
        return env.remove(propName);
    }

    public Hashtable getEnv() {
        return env;
    }

    @Override
    public void close() throws NamingException {
        env.clear();
    }

    @Override
    public abstract String getNameInNamespace() throws NamingException;

    @Override
    public Attributes getAttributes(Name name) throws NamingException {
        return getAttributes(name.toString());
    }

    @Override
    public Attributes getAttributes(String name) throws NamingException {
        return getAttributes(name,null);
    }

    @Override
    public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
        return getAttributes(name.toString(),attrIds);
    }

    public abstract Attributes getAttributes(String name, String[] attrIds)
            throws NamingException;

    public void modifyAttributes(Name name, int mod_op, Attributes attrs)
            throws NamingException {
        modifyAttributes(name.toString(), mod_op, attrs);
    }

    public abstract void modifyAttributes
            (String name, int mod_op, Attributes attrs)
            throws NamingException;

    public void modifyAttributes(Name name, ModificationItem[] mods)
            throws NamingException {
        modifyAttributes(name.toString(), mods);
    }

    public abstract void modifyAttributes(String name, ModificationItem[] mods)
            throws NamingException;

    public void bind(Name name, Object obj, Attributes attrs)
            throws NamingException {
        bind(name.toString(), obj, attrs);
    }

    public abstract void bind(String name, Object obj, Attributes attrs)
            throws NamingException;


    public void rebind(Name name, Object obj, Attributes attrs)
            throws NamingException {
        rebind(name.toString(), obj, attrs);
    }

    public abstract void rebind(String name, Object obj, Attributes attrs)
            throws NamingException;

    public DirContext createSubcontext(Name name, Attributes attrs)
            throws NamingException {
        return createSubcontext(name.toString(), attrs);
    }

    public abstract DirContext createSubcontext(String name, Attributes attrs)
            throws NamingException;

    public DirContext getSchema(Name name)
            throws NamingException {
        return getSchema(name.toString());
    }

    public abstract DirContext getSchema(String name)
            throws NamingException;

    public DirContext getSchemaClassDefinition(Name name)
            throws NamingException {
        return getSchemaClassDefinition(name.toString());
    }

    public abstract DirContext getSchemaClassDefinition(String name)
            throws NamingException;

    public NamingEnumeration<SearchResult> search(Name name, Attributes matchingAttributes,
                                                  String[] attributesToReturn)
            throws NamingException {
        return search(name.toString(), matchingAttributes, attributesToReturn);
    }

    public abstract NamingEnumeration<SearchResult> search
            (String name, Attributes matchingAttributes,
             String[] attributesToReturn)
            throws NamingException;

    public NamingEnumeration<SearchResult> search(Name name, Attributes matchingAttributes)
            throws NamingException {
        return search(name.toString(), matchingAttributes);
    }

    public abstract NamingEnumeration<SearchResult> search
            (String name, Attributes matchingAttributes)
            throws NamingException;

    public abstract NamingEnumeration<SearchResult> search(String name, String filter,
                                             SearchControls cons)
            throws NamingException;

    public NamingEnumeration<SearchResult> search(Name name, String filterExpr,
                                    Object[] filterArgs, SearchControls cons)
            throws NamingException {
        return search(name.toString(), filterExpr, filterArgs, cons);
    }

    public abstract NamingEnumeration<SearchResult> search
            (String name, String filterExpr,
             Object[] filterArgs, SearchControls cons)
            throws NamingException;
}
